/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "zlang_in.h"

#define CHECK_CONSTANT_OBJECT(_obj_) \
	if( IsConstantObject(_obj_) ) \
	{ \
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_CANNOT_COPY_TO_A_CONSTANT , "can't copy to a constant" ) \
		return ZLANG_ERROR_CANNOT_COPY_TO_A_CONSTANT; \
	} \

void SetCheckingErrorNo( struct ZlangRuntime *rt , int error_no )
{
	rt->checking_error_no = error_no ;
	return;
}

int GetCheckingErrorNo( struct ZlangRuntime *rt )
{
	return rt->checking_error_no;
}

void SetRuntimeError( struct ZlangRuntime *rt , int runtime_error_level , int runtime_error_no , char *debug_internal_file , int debug_internal_lineno , char *runtime_error_string_format , ... )
{
	va_list		valist ;
	
	if( rt->runtime_error_no )
		return;
	
	rt->error_token_info = rt->travel_token_info ;
	rt->error_token = rt->travel_token ;
	rt->runtime_error_level = runtime_error_level ;
	rt->runtime_error_no = runtime_error_no ;
	rt->debug_internal_file = debug_internal_file ;
	rt->debug_internal_lineno = debug_internal_lineno ;
	
	va_start( valist , runtime_error_string_format );
	memset( rt->runtime_error_string , 0x00 , sizeof(rt->runtime_error_string) );
	vsnprintf( rt->runtime_error_string , sizeof(rt->runtime_error_string)-1 , runtime_error_string_format , valist );
	va_end( valist );
	
	return;
}

void CleanRuntimeError( struct ZlangRuntime *rt )
{
	rt->runtime_error_no = 0 ;
	return;
}

char *GetRuntimeErrorString( struct ZlangRuntime *rt )
{
	return rt->runtime_error_string;
}

void FillRuntimeErrorString( struct ZlangRuntime *rt , char *buf , size_t buf_size)
{
	if( rt->debug_error_level == RUNTIME_DEBUG )
	{
		snprintf( buf , buf_size-1 , "*** %s %s:%"PRIi32",%"PRIi32":'%s' %d: %s (%s:%d)"
			, _zlang_runtime_error_level[rt->runtime_error_level]
			, rt->error_token_info ? rt->error_token_info->source_filename : "_"
			, rt->error_token_info ? rt->error_token_info->source_row : 0
			, rt->error_token_info ? rt->error_token_info->source_col : 0
			, rt->error_token ? rt->error_token : ""
			, rt->runtime_error_no , rt->runtime_error_string
			, rt->debug_internal_file , rt->debug_internal_lineno );
	}
	else
	{
		snprintf( buf , buf_size-1 , "*** %s %s:%"PRIi32",%"PRIi32":'%s' %d: %s"
			, _zlang_runtime_error_level[rt->runtime_error_level]
			, rt->error_token_info ? rt->error_token_info->source_filename : "_"
			, rt->error_token_info ? rt->error_token_info->source_row : 0
			, rt->error_token_info ? rt->error_token_info->source_col : 0
			, rt->error_token ? rt->error_token : ""
			, rt->runtime_error_no , rt->runtime_error_string );
	}
	return;
}

void CopyRuntimeError( struct ZlangRuntime *rt , struct ZlangRuntime *copy_rt )
{
	rt->error_token_info = copy_rt->error_token_info ;
	rt->error_token = copy_rt->error_token ;
	rt->runtime_error_level = copy_rt->runtime_error_level ;
	rt->runtime_error_no = copy_rt->runtime_error_no ;
	rt->debug_internal_file = copy_rt->debug_internal_file ;
	rt->debug_internal_lineno = copy_rt->debug_internal_lineno ;
	
	strcpy( rt->runtime_error_string , copy_rt->runtime_error_string );
	
	return;
}

int GetRuntimeErrorLevel( struct ZlangRuntime *rt )
{
	return rt->runtime_error_no;
}

int GetRuntimeErrorNo( struct ZlangRuntime *rt )
{
	return rt->runtime_error_no;
}

int GetRuntimeDebugErrorLevel( struct ZlangRuntime *rt )
{
	return rt->debug_error_level;
}

char *GetRuntimeDebugErrorLevelStringPtr( struct ZlangRuntime *rt )
{
	return rt->debug_error_level_str;
}

char *GetRuntimeFullCharsetString( struct ZlangRuntime *rt )
{
	return rt->full_charset_str;
}

char *GetRuntimeCharsetString( struct ZlangRuntime *rt )
{
	return rt->charset_str;
}

int16_t GetRuntimeCharset( struct ZlangRuntime *rt )
{
	return rt->charset;
}

char *GetZlangPathfilename( struct ZlangRuntime *rt )
{
	return rt->zlang_pathfilename;
}

char *GetZlangPathname( struct ZlangRuntime *rt )
{
	return rt->zlang_pathname;
}

char *GetZlangFilename( struct ZlangRuntime *rt )
{
	return rt->zlang_filename;
}

char *GetFirstZFilePathname( struct ZlangRuntime *rt )
{
	return rt->first_z_file_pathname;
}

unsigned char GetCheckingMode( struct ZlangRuntime *rt )
{
	return rt->checking_mode;
}

struct ZlangObject *GetRuntimeInObject( struct ZlangRuntime *rt )
{
	return rt->in_obj;
}

void SetRuntimeInObject( struct ZlangRuntime *rt , struct ZlangObject *in_obj )
{
	rt->in_obj = in_obj ;
	return;
}

struct ZlangFunction *GetRuntimeInFunction( struct ZlangRuntime *rt )
{
	return rt->in_func;
}

void SetRuntimeInFunction( struct ZlangRuntime *rt , struct ZlangFunction *in_func )
{
	rt->in_func = in_func ;
	return;
}

int ImportObject( struct ZlangRuntime *rt , struct ZlangObject **pp_obj , char *obj_name , struct ZlangDirectFunctions *direct_funcs , size_t sizeof_direct_funcs , struct ZlangObject *inherit_obj )
{
	struct ZlangObject	*obj = NULL ;
	int			nret = 0 ;
	
	if( sizeof_direct_funcs != sizeof(struct ZlangDirectFunctions) )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_DIRECT_FUNCTIONS_VERSION_NOT_MATCHED , "direct functions version not matched on import object[%s]" , GetObjectName(obj) )
		return ZLANG_ERROR_DIRECT_FUNCTIONS_VERSION_NOT_MATCHED;
	}
	
	obj = AllocObject( rt ) ;
	if( obj == NULL )
		return GET_RUNTIME_ERROR_NO(rt);
	
	nret = InitObject( rt , obj , obj_name , direct_funcs , 0 ) ;
	if( nret )
	{
		DestroyObject( rt , obj );
		return nret;
	}
	
	nret = ImportObjectToGlobalObjectsHeap( rt , obj , inherit_obj ) ;
	if( nret )
	{
		DestroyObject( rt , obj );
		return nret;
	}
	
	if( pp_obj )
		(*pp_obj) = obj ;
	return 0;
}

int ImportObjectToGlobalObjectsHeap( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *inherit_obj )
{
	char			*obj_name = NULL ;
	struct ZlangObject	*zobj = NULL ;
	int			nret = 0 ;
	
	nret = LinkObjectToRuntimeObjectsHeapByObjectName( rt , obj ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "LinkObjectToRuntimeObjectsHeapByObjectName obj[%s] failed[%d]" , GetObjectName(obj) , nret )
		return ZLANG_ERROR_LINK_FUNC_TO_ENTITY;
	}
	else
	{
		/*
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "LinkObjectToRuntimeObjectsHeapByObjectName obj[%s] ok" , GetObjectName(obj) )
		*/
	}
	
	list_add_tail( & (obj->obj_order_imported_node) , & (rt->global_order_imported_objs_list) );
	
	obj_name = GetObjectName( obj ) ;
	if( obj_name )
	{
		if( STRCMP( obj_name , == , ZLANG_OBJECT_zobject ) )
			rt->frequent_objs.zobject_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_zruntime ) )
			rt->frequent_objs.zruntime_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_error ) )
			rt->frequent_objs.error_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_fatal ) )
			rt->frequent_objs.fatal_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_string ) )
			rt->frequent_objs.string_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_bool ) )
			rt->frequent_objs.bool_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_short ) )
			rt->frequent_objs.short_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_ushort ) )
			rt->frequent_objs.ushort_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_int ) )
			rt->frequent_objs.int_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_uint ) )
			rt->frequent_objs.uint_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_long ) )
			rt->frequent_objs.long_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_ulong ) )
			rt->frequent_objs.ulong_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_float ) )
			rt->frequent_objs.float_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_double ) )
			rt->frequent_objs.double_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_array ) )
			rt->frequent_objs.array_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_list ) )
			rt->frequent_objs.list_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_list_node ) )
			rt->frequent_objs.list_node_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_map ) )
			rt->frequent_objs.map_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_iterator ) )
			rt->frequent_objs.iterator_obj = obj ;
		else if( STRCMP( obj_name , == , ZLANG_OBJECT_functionptr ) )
			rt->frequent_objs.functionptr_obj = obj ;
		
		if( STRCMP( obj_name , != , ZLANG_OBJECT_zobject ) )
		{
			if( inherit_obj )
			{
				SetObjectAncestorFunctionsEntity( rt , obj , GetObjectFunctionsEntity(GetZObjectInRuntimeObjectsHeap(rt)) );
				
				nret = CopyObjectProperties( rt , obj , inherit_obj ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CopyObjectProperties failed[%d]" , nret )
					return nret;
				}
			}
			
			zobj = GetZObjectInRuntimeObjectsHeap(rt) ;
			if( GetObjectAncestorAncestorFunctionsEntity(obj) != GetObjectFunctionsEntity(zobj) )
			{
				SetObjectAncestorAncestorFunctionsEntity( rt , obj , GetObjectFunctionsEntity(zobj) );
				
				nret = CopyObjectProperties( rt , obj , zobj ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CopyObjectProperties zobj failed[%d]" , nret )
					return nret;
				}
			}
		}
		
	}
	
	return 0;
}

struct ZlangObject *GetZObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.zobject_obj;
}

struct ZlangObject *GetStringObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.string_obj;
}

struct ZlangObject *GetBoolObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.bool_obj;
}

struct ZlangObject *GetShortObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.short_obj;
}

struct ZlangObject *GetUShortObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.ushort_obj;
}

struct ZlangObject *GetIntObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.int_obj;
}

struct ZlangObject *GetUIntObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.uint_obj;
}

struct ZlangObject *GetLongObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.long_obj;
}

struct ZlangObject *GetULongObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.ulong_obj;
}

struct ZlangObject *GetFloatObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.float_obj;
}

struct ZlangObject *GetDoubleObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.double_obj;
}

struct ZlangObject *GetArrayObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.array_obj;
}

struct ZlangObject *GetListObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.list_obj;
}

struct ZlangObject *GetListNodeObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.list_node_obj;
}

struct ZlangObject *GetMapObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.map_obj;
}

struct ZlangObject *GetIteratorObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.iterator_obj;
}

struct ZlangObject *GetFunctionPtrObjectInRuntimeObjectsHeap( struct ZlangRuntime *rt )
{
	return rt->frequent_objs.functionptr_obj;
}

void SetRuntimeFunction_string_AppendFormatFromArgsStack( struct ZlangRuntime *rt , ZlangInvokeFunction *func )
{
	rt->invoke_funcs.string_AppendFormatFromArgsStack_func = func ;
	return;
}

void SetRuntimeFunction_string_Clear( struct ZlangRuntime *rt , ZlangDirectFunction_string_Clear *func )
{
	rt->direct_funcs.string_Clear_func = func ;
	return;
}

void SetRuntimeFunction_string_PrepareBuffer( struct ZlangRuntime *rt , ZlangDirectFunction_string_PrepareBuffer *func )
{
	rt->direct_funcs.string_PrepareBuffer_func = func ;
	return;
}

void SetRuntimeFunction_string_GetDirectPropertiesPtr( struct ZlangRuntime *rt , ZlangDirectFunction_string_GetDirectPropertiesPtr *func )
{
	rt->direct_funcs.string_GetDirectPropertiesPtr_func = func ;
	return;
}

int CallRuntimeFunction_string_AppendFormatFromArgsStack( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->invoke_funcs.string_AppendFormatFromArgsStack_func == NULL )
		return ZLANG_ERROR_RUNTIME_INVOKE_FUNCTION_NOT_SETED;
	
	return rt->invoke_funcs.string_AppendFormatFromArgsStack_func( rt , obj );
}

int CallRuntimeFunction_string_Clear( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_Clear_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.string_Clear_func( rt , obj );
}

int CallRuntimeFunction_string_PrepareBuffer( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t prepare_len )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_PrepareBuffer_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.string_PrepareBuffer_func( rt , obj , prepare_len );
}

int CallRuntimeFunction_string_GetDirectPropertiesPtr( struct ZlangRuntime *rt , struct ZlangObject *obj , char ***buf , int32_t **buf_size , int32_t **buf_len )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_GetDirectPropertiesPtr_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.string_GetDirectPropertiesPtr_func( rt , obj , buf , buf_size , buf_len );
}

void SetRuntimeFunction_array_Append( struct ZlangRuntime *rt , ZlangDirectFunction_array_Append *func )
{
	rt->direct_funcs.array_Append_func = func ;
	return;
}

void SetRuntimeFunction_array_InsertBefore( struct ZlangRuntime *rt , ZlangDirectFunction_array_InsertBefore *func )
{
	rt->direct_funcs.array_InsertBefore_func = func ;
	return;
}

void SetRuntimeFunction_array_Remove( struct ZlangRuntime *rt , ZlangDirectFunction_array_Remove *func )
{
	rt->direct_funcs.array_Remove_func = func ;
	return;
}

void SetRuntimeFunction_array_RemoveAll( struct ZlangRuntime *rt , ZlangDirectFunction_array_RemoveAll *func )
{
	rt->direct_funcs.array_RemoveAll_func = func ;
	return;
}

void SetRuntimeFunction_array_Length( struct ZlangRuntime *rt , ZlangDirectFunction_array_Length *func )
{
	rt->direct_funcs.array_Length_func = func ;
	return;
}

void SetRuntimeFunction_array_Get( struct ZlangRuntime *rt , ZlangDirectFunction_array_Get *func )
{
	rt->direct_funcs.array_Get_func = func ;
	return;
}

void SetRuntimeFunction_array_Set( struct ZlangRuntime *rt , ZlangDirectFunction_array_Set *func )
{
	rt->direct_funcs.array_Set_func = func ;
	return;
}

int CallRuntimeFunction_array_Append( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *element , struct ZlangObject **append )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_Append_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_Append_func( rt , obj , element , append );
}

int CallRuntimeFunction_array_InsertBefore( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t element_no , struct ZlangObject *element , struct ZlangObject **insert )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_InsertBefore_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_InsertBefore_func( rt , obj , element_no , element , insert );
}

int CallRuntimeFunction_array_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t element_no )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_Remove_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_Remove_func( rt , obj , element_no );
}

int CallRuntimeFunction_array_RemoveAll( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_RemoveAll_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_RemoveAll_func( rt , obj );
}

int CallRuntimeFunction_array_Length( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *array_length )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_Length_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_Length_func( rt , obj , array_length );
}

int CallRuntimeFunction_array_Get( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t element_no , struct ZlangObject **element )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_Get_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_Get_func( rt , obj , element_no , element );
}

int CallRuntimeFunction_array_Set( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t element_no , struct ZlangObject *element )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.array_Set_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.array_Set_func( rt , obj , element_no , element );
}

void SetRuntimeFunction_list_AddHead( struct ZlangRuntime *rt , ZlangDirectFunction_list_AddHead *func )
{
	rt->direct_funcs.list_AddHead_func = func ;
	return;
}

void SetRuntimeFunction_list_AddTail( struct ZlangRuntime *rt , ZlangDirectFunction_list_AddTail *func )
{
	rt->direct_funcs.list_AddTail_func = func ;
	return;
}

void SetRuntimeFunction_list_RemoveAll( struct ZlangRuntime *rt , ZlangDirectFunction_list_RemoveAll *func )
{
	rt->direct_funcs.list_RemoveAll_func = func ;
	return;
}

void SetRuntimeFunction_list_GetHead( struct ZlangRuntime *rt , ZlangDirectFunction_list_GetHead *func )
{
	rt->direct_funcs.list_GetHead_func = func ;
	return;
}

void SetRuntimeFunction_list_GetTail( struct ZlangRuntime *rt , ZlangDirectFunction_list_GetTail *func )
{
	rt->direct_funcs.list_GetTail_func = func ;
	return;
}

void SetRuntimeFunction_list_Length( struct ZlangRuntime *rt , ZlangDirectFunction_list_Length *func )
{
	rt->direct_funcs.list_Length_func = func ;
	return;
}

void SetRuntimeFunction_list_IsEmpty( struct ZlangRuntime *rt , ZlangDirectFunction_list_IsEmpty *func )
{
	rt->direct_funcs.list_IsEmpty_func = func ;
	return;
}

void SetRuntimeFunction_list_IsNotEmpty( struct ZlangRuntime *rt , ZlangDirectFunction_list_IsNotEmpty *func )
{
	rt->direct_funcs.list_IsNotEmpty_func = func ;
	return;
}

void SetRuntimeFunction_list_node_TravelNext( struct ZlangRuntime *rt , ZlangDirectFunction_list_node_TravelNext *func )
{
	rt->direct_funcs.list_node_TravelNext_func = func ;
	return;
}

void SetRuntimeFunction_list_node_TravelPrev( struct ZlangRuntime *rt , ZlangDirectFunction_list_node_TravelPrev *func )
{
	rt->direct_funcs.list_node_TravelPrev_func = func ;
	return;
}

void SetRuntimeFunction_list_node_IsTravelOver( struct ZlangRuntime *rt , ZlangDirectFunction_list_node_IsTravelOver *func )
{
	rt->direct_funcs.list_node_IsTravelOver_func = func ;
	return;
}

void SetRuntimeFunction_list_node_Remove( struct ZlangRuntime *rt , ZlangDirectFunction_list_node_Remove *func )
{
	rt->direct_funcs.list_node_Remove_func = func ;
	return;
}

void SetRuntimeFunction_list_node_GetMember( struct ZlangRuntime *rt , ZlangDirectFunction_list_node_GetMember *func )
{
	rt->direct_funcs.list_node_GetMember_func = func ;
	return;
}

int CallRuntimeFunction_list_AddHead( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *element , struct ZlangObject **add )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_AddHead_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_AddHead_func( rt , obj , element , add );
}

int CallRuntimeFunction_list_AddTail( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *element , struct ZlangObject **add )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_AddTail_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_AddTail_func( rt , obj , element , add );
}

int CallRuntimeFunction_list_RemoveAll( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_RemoveAll_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_RemoveAll_func( rt , obj );
}

int CallRuntimeFunction_list_GetHead( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **list_node )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_GetHead_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_GetHead_func( rt , obj , list_node );
}

int CallRuntimeFunction_list_GetTail( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **list_node )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_GetTail_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_GetTail_func( rt , obj , list_node );
}

int CallRuntimeFunction_list_Length( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *list_length )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_Length_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_Length_func( rt , obj , list_length );
}

int CallRuntimeFunction_list_IsEmpty( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char *b )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_IsEmpty_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_IsEmpty_func( rt , obj , b );
}

int CallRuntimeFunction_list_IsNotEmpty( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char *b )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_IsNotEmpty_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_IsNotEmpty_func( rt , obj , b );
}

int CallRuntimeFunction_list_node_TravelNext( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_node_TravelNext_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_node_TravelNext_func( rt , obj );
}

int CallRuntimeFunction_list_node_TravelPrev( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_node_TravelPrev_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_node_TravelPrev_func( rt , obj );
}

int CallRuntimeFunction_list_node_IsTravelOver( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_node_IsTravelOver_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_node_IsTravelOver_func( rt , obj );
}

int CallRuntimeFunction_list_node_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_node_Remove_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_node_Remove_func( rt , obj );
}

int CallRuntimeFunction_list_node_GetMember( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **element )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.list_node_GetMember_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.list_node_GetMember_func( rt , obj , element );
}


void SetRuntimeFunction_map_Put( struct ZlangRuntime *rt , ZlangDirectFunction_map_Put *func )
{
	rt->direct_funcs.map_Put_func = func ;
	return;
}

void SetRuntimeFunction_map_Get( struct ZlangRuntime *rt , ZlangDirectFunction_map_Get *func )
{
	rt->direct_funcs.map_Get_func = func ;
	return;
}

void SetRuntimeFunction_map_TravelNextKey( struct ZlangRuntime *rt , ZlangDirectFunction_map_TravelNextKey *func )
{
	rt->direct_funcs.map_TravelNextKey_func = func ;
	return;
}

void SetRuntimeFunction_map_TravelPrevKey( struct ZlangRuntime *rt , ZlangDirectFunction_map_TravelPrevKey *func )
{
	rt->direct_funcs.map_TravelPrevKey_func = func ;
	return;
}

void SetRuntimeFunction_map_UpdateKey( struct ZlangRuntime *rt , ZlangDirectFunction_map_UpdateKey *func )
{
	rt->direct_funcs.map_UpdateKey_func = func ;
	return;
}

void SetRuntimeFunction_map_Remove( struct ZlangRuntime *rt , ZlangDirectFunction_map_Remove *func )
{
	rt->direct_funcs.map_Remove_func = func ;
	return;
}

void SetRuntimeFunction_map_RemoveAll( struct ZlangRuntime *rt , ZlangDirectFunction_map_RemoveAll *func )
{
	rt->direct_funcs.map_RemoveAll_func = func ;
	return;
}

void SetRuntimeFunction_map_Length( struct ZlangRuntime *rt , ZlangDirectFunction_map_Length *func )
{
	rt->direct_funcs.map_Length_func = func ;
	return;
}

int CallRuntimeFunction_map_Put( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *key , struct ZlangObject *value , struct ZlangObject **add )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_Put_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_Put_func( rt , obj , key , value , add );
}

int CallRuntimeFunction_map_Get( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *key , struct ZlangObject **value )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_Get_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_Get_func( rt , obj , key , value );
}

int CallRuntimeFunction_map_TravelNextKey( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **key )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_TravelNextKey_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_TravelNextKey_func( rt , obj , key );
}

int CallRuntimeFunction_map_TravelPrevKey( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **key )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_TravelPrevKey_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_TravelPrevKey_func( rt , obj , key );
}

int CallRuntimeFunction_map_UpdateKey( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *old_key , struct ZlangObject *new_key )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_UpdateKey_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_UpdateKey_func( rt , obj , old_key , new_key );
}

int CallRuntimeFunction_map_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **key )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_Remove_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_Remove_func( rt , obj , key );
}

int CallRuntimeFunction_map_RemoveAll( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_RemoveAll_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_RemoveAll_func( rt , obj );
}

int CallRuntimeFunction_map_Length( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *map_length )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.map_Length_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.map_Length_func( rt , obj , map_length );
}

void SetRuntimeFunction_iterator_TravelFirst( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_TravelFirst *func )
{
	rt->direct_funcs.iterator_TravelFirst_func = func ;
	return;
}

void SetRuntimeFunction_iterator_TravelLast( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_TravelLast *func )
{
	rt->direct_funcs.iterator_TravelLast_func = func ;
	return;
}

void SetRuntimeFunction_iterator_TravelNext( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_TravelNext *func )
{
	rt->direct_funcs.iterator_TravelNext_func = func ;
	return;
}

void SetRuntimeFunction_iterator_TravelPrev( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_TravelPrev *func )
{
	rt->direct_funcs.iterator_TravelPrev_func = func ;
	return;
}

void SetRuntimeFunction_iterator_IsTravelOver( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_IsTravelOver *func )
{
	rt->direct_funcs.iterator_IsTravelOver_func = func ;
	return;
}

void SetRuntimeFunction_iterator_GetElement( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_GetElement *func )
{
	rt->direct_funcs.iterator_GetElement_func = func ;
	return;
}

void SetRuntimeFunction_iterator_Remove( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_Remove *func )
{
	rt->direct_funcs.iterator_Remove_func = func ;
	return;
}

void SetRuntimeFunction_iterator_Length( struct ZlangRuntime *rt , ZlangDirectFunction_iterator_Length *func )
{
	rt->direct_funcs.iterator_Length_func = func ;
	return;
}

int CallRuntimeFunction_iterator_TravelFirst( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *collect_obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_TravelFirst_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_TravelFirst_func( rt , obj , collect_obj );
}

int CallRuntimeFunction_iterator_TravelLast( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *collect_obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_TravelLast_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_TravelLast_func( rt , obj , collect_obj );
}

int CallRuntimeFunction_iterator_TravelNext( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_TravelNext_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_TravelNext_func( rt , obj );
}

int CallRuntimeFunction_iterator_TravelPrev( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_TravelPrev_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_TravelPrev_func( rt , obj );
}

int CallRuntimeFunction_iterator_IsTravelOver( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_IsTravelOver_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_IsTravelOver_func( rt , obj );
}

int CallRuntimeFunction_iterator_GetElement( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **element_obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_GetElement_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_GetElement_func( rt , obj , element_obj );
}

int CallRuntimeFunction_iterator_Remove( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_Remove_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_Remove_func( rt , obj );
}

int CallRuntimeFunction_iterator_Length( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *length )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.iterator_Length_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.iterator_Length_func( rt , obj , length );
}

void SetRuntimeFunction_json_StringToObject( struct ZlangRuntime *rt , ZlangDirectFunction_json_StringToObject *func )
{
	rt->direct_funcs.json_StringToObject_func = func ;
	return;
}

void SetRuntimeFunction_json_StringToEntityObject( struct ZlangRuntime *rt , ZlangDirectFunction_json_StringToEntityObject *func )
{
	rt->direct_funcs.json_StringToEntityObject_func = func ;
	return;
}

void SetRuntimeFunction_json_ObjectToString( struct ZlangRuntime *rt , ZlangDirectFunction_json_ObjectToString *func )
{
	rt->direct_funcs.json_ObjectToString_func = func ;
	return;
}

ZlangDirectFunction_json_StringToObject *GetRuntimeFunction_json_StringToObject( struct ZlangRuntime *rt )
{
	return rt->direct_funcs.json_StringToObject_func;
}

ZlangDirectFunction_json_ObjectToString *GetRuntimeFunction_json_ObjectToString( struct ZlangRuntime *rt )
{
	return rt->direct_funcs.json_ObjectToString_func;
}

int CallRuntimeFunction_json_StringToObject( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *t , struct ZlangObject *o )
{
	if( rt->direct_funcs.json_StringToObject_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.json_StringToObject_func( rt , obj , t , o );
}

int CallRuntimeFunction_json_StringToEntityObject( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *t , struct ZlangObject *o )
{
	if( rt->direct_funcs.json_StringToEntityObject_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.json_StringToEntityObject_func( rt , obj , t , o );
}

int CallRuntimeFunction_json_ObjectToString( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *o , struct ZlangObject *t , int32_t obj_to_str_style )
{
	if( rt->direct_funcs.json_ObjectToString_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.json_ObjectToString_func( rt , obj , o , t , obj_to_str_style );
}

void SetRuntimeFunction_xml_StringToObject( struct ZlangRuntime *rt , ZlangDirectFunction_xml_StringToObject *func )
{
	rt->direct_funcs.xml_StringToObject_func = func ;
	return;
}

void SetRuntimeFunction_xml_StringToEntityObject( struct ZlangRuntime *rt , ZlangDirectFunction_xml_StringToEntityObject *func )
{
	rt->direct_funcs.xml_StringToEntityObject_func = func ;
	return;
}

void SetRuntimeFunction_xml_ObjectToString( struct ZlangRuntime *rt , ZlangDirectFunction_xml_ObjectToString *func )
{
	rt->direct_funcs.xml_ObjectToString_func = func ;
	return;
}

ZlangDirectFunction_xml_StringToObject *GetRuntimeFunction_xml_StringToObject( struct ZlangRuntime *rt )
{
	return rt->direct_funcs.xml_StringToObject_func;
}

ZlangDirectFunction_xml_ObjectToString *GetRuntimeFunction_xml_ObjectToString( struct ZlangRuntime *rt )
{
	return rt->direct_funcs.xml_ObjectToString_func;
}

int CallRuntimeFunction_xml_StringToObject( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *t , struct ZlangObject *o )
{
	if( rt->direct_funcs.xml_StringToObject_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.xml_StringToObject_func( rt , obj , t , o );
}

int CallRuntimeFunction_xml_StringToEntityObject( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *t , struct ZlangObject *o )
{
	if( rt->direct_funcs.xml_StringToEntityObject_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.xml_StringToEntityObject_func( rt , obj , t , o );
}

int CallRuntimeFunction_xml_ObjectToString( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *o , struct ZlangObject *t , int32_t obj_to_str_style )
{
	if( rt->direct_funcs.xml_ObjectToString_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.xml_ObjectToString_func( rt , obj , o , t , obj_to_str_style );
}

#define SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(_basetype_,_Basetype_) \
	void SetRuntimeFunction_##_basetype_##_Set##_Basetype_( struct ZlangRuntime *rt , ZlangDirectFunction_##_basetype_##_Set##_Basetype_ *func ) \
	{ \
		rt->direct_funcs._basetype_##_Set##_Basetype_##_func = func ; \
		return; \
	} \
	\
	void SetRuntimeFunction_##_basetype_##_Get##_Basetype_( struct ZlangRuntime *rt , ZlangDirectFunction_##_basetype_##_Get##_Basetype_ *func ) \
	{ \
		rt->direct_funcs._basetype_##_Get##_Basetype_##_func = func ; \
		return; \
	} \

#define CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(_basetype_,_Basetype_,_ctype_) \
	int CallRuntimeFunction_##_basetype_##_Set##_Basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , _ctype_ value ) \
	{ \
		CHECK_CONSTANT_OBJECT(obj); \
		if( rt->direct_funcs._basetype_##_Set##_Basetype_##_func == NULL ) \
			return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED; \
		\
		return rt->direct_funcs._basetype_##_Set##_Basetype_##_func( rt , obj , value ); \
	} \
	\
	int CallRuntimeFunction_##_basetype_##_Get##_Basetype_( struct ZlangRuntime *rt , struct ZlangObject *obj , _ctype_ *value ) \
	{ \
		if( rt->direct_funcs._basetype_##_Get##_Basetype_##_func == NULL ) \
			return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED; \
		\
		return rt->direct_funcs._basetype_##_Get##_Basetype_##_func( rt , obj , value ); \
	} \

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(string,StringValue)
void SetRuntimeFunction_string_FormatStringValue( struct ZlangRuntime *rt , ZlangDirectFunction_string_FormatStringValue *func )
{
	rt->direct_funcs.string_FormatStringValue_func = func ;
	return;
}
void SetRuntimeFunction_string_AppendStringValue( struct ZlangRuntime *rt , ZlangDirectFunction_string_AppendStringValue *func )
{
	rt->direct_funcs.string_AppendStringValue_func = func ;
	return;
}
void SetRuntimeFunction_string_AppendFormatStringValue( struct ZlangRuntime *rt , ZlangDirectFunction_string_AppendFormatStringValue *func )
{
	rt->direct_funcs.string_AppendFormatStringValue_func = func ;
	return;
}
void SetRuntimeFunction_string_ExpandEnvironmentVar( struct ZlangRuntime *rt , ZlangDirectFunction_string_ExpandEnvironmentVar *func )
{
	rt->direct_funcs.string_ExpandEnvironmentVar_func = func ;
	return;
}
int CallRuntimeFunction_string_SetStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *value , int32_t value_len )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_SetStringValue_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.string_SetStringValue_func( rt , obj , value , value_len );
}
int CallRuntimeFunction_string_FormatStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *format , ... )
{
	va_list		valist ;
	int		nret = 0 ;
	
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_FormatStringValue_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	va_start( valist , format );
	nret = rt->direct_funcs.string_FormatStringValue_func( rt , obj , format , valist ) ;
	va_end( valist );
	
	return nret;
}
int CallRuntimeFunction_string_AppendStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *value , int32_t value_len )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_AppendStringValue_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.string_AppendStringValue_func( rt , obj , value , value_len );
}
int CallRuntimeFunction_string_AppendFormatStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char *format , ... )
{
	va_list		valist ;
	int		nret = 0 ;
	
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.string_AppendFormatStringValue_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	va_start( valist , format );
	nret = rt->direct_funcs.string_AppendFormatStringValue_func( rt , obj , format , valist ) ;
	va_end( valist );
	
	return nret;
}
int CallRuntimeFunction_string_ExpandEnvironmentVar( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	return rt->direct_funcs.string_ExpandEnvironmentVar_func( rt , obj );
}
int CallRuntimeFunction_string_GetStringValue( struct ZlangRuntime *rt , struct ZlangObject *obj , char **value , int32_t *value_len )
{
	if( rt->direct_funcs.string_GetStringValue_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.string_GetStringValue_func( rt , obj , value , value_len );
}

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(bool,BoolValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(bool,BoolValue,unsigned char)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(short,ShortValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(short,ShortValue,int16_t)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(ushort,UShortValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(ushort,UShortValue,uint16_t)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(int,IntValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(int,IntValue,int32_t)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(uint,UIntValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(uint,UIntValue,uint32_t)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(long,LongValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(long,LongValue,int64_t)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(ulong,ULongValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(ulong,ULongValue,uint64_t)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(float,FloatValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(float,FloatValue,float)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(double,DoubleValue)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(double,DoubleValue,double)

SETDIRECTFUNCTION_SETANDGETBASETYPEVALUE(functionptr,FunctionPtr)
CALLDIRECTFUNCTION_SETANDGETBASETYPEVALUE(functionptr,FunctionPtr,struct ZlangFunction *)

void SetRuntimeFunction_functionptr_SetObjectPtr( struct ZlangRuntime *rt , ZlangDirectFunction_functionptr_SetObjectPtr *func )
{
	rt->direct_funcs.functionptr_SetObjectPtr_func = func ;
	return;
}

void SetRuntimeFunction_functionptr_GetObjectPtr( struct ZlangRuntime *rt , ZlangDirectFunction_functionptr_GetObjectPtr *func )
{
	rt->direct_funcs.functionptr_GetObjectPtr_func = func ;
	return;
}

int CallRuntimeFunction_functionptr_SetObjectPtr( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *value )
{
	CHECK_CONSTANT_OBJECT(obj);
	if( rt->direct_funcs.functionptr_SetObjectPtr_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.functionptr_SetObjectPtr_func( rt , obj , value );
}

int CallRuntimeFunction_functionptr_GetObjectPtr( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject **value )
{
	if( rt->direct_funcs.functionptr_GetObjectPtr_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.functionptr_GetObjectPtr_func( rt , obj , value );
}

void SetRuntimeFunction_mutex_GetMutexPtr( struct ZlangRuntime *rt , ZlangDirectFunction_mutex_GetMutexPtr *func )
{
	rt->direct_funcs.mutex_GetMutexPtr_func = func ;
	return;
}

int CallRuntimeFunction_mutex_GetMutexPtr( struct ZlangRuntime *rt , struct ZlangObject *obj , MUTEX **mutex )
{
	if( rt->direct_funcs.mutex_GetMutexPtr_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.mutex_GetMutexPtr_func( rt , obj , mutex );
}

void SetRuntimeFunction_condsig_GetMutexPtr( struct ZlangRuntime *rt , ZlangDirectFunction_condsig_GetMutexPtr *func )
{
	rt->direct_funcs.condsig_GetMutexPtr_func = func ;
	return;
}

int CallRuntimeFunction_condsig_GetMutexPtr( struct ZlangRuntime *rt , struct ZlangObject *obj , MUTEX **mutex )
{
	if( rt->direct_funcs.condsig_GetMutexPtr_func == NULL )
		return ZLANG_ERROR_RUNTIME_DIRECT_FUNCTION_NOT_SETED;
	
	return rt->direct_funcs.condsig_GetMutexPtr_func( rt , obj , mutex );
}

void SetRuntimeFunction_error_ThrowException( struct ZlangRuntime *rt , ZlangDirectFunction_error_ThrowException *func )
{
	rt->direct_funcs.error_ThrowException_func = func ;
	return;
}

void SetRuntimeFunction_error_HaveException( struct ZlangRuntime *rt , ZlangDirectFunction_error_HaveException *func )
{
	rt->direct_funcs.error_HaveException_func = func ;
	return;
}

void SetRuntimeFunction_error_GetMessage( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetMessage *func )
{
	rt->direct_funcs.error_GetMessage_func = func ;
	return;
}

void SetRuntimeFunction_error_GetExceptionSourceFilename( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetExceptionSourceFilename *func )
{
	rt->direct_funcs.error_GetExceptionSourceFilename_func = func ;
	return;
}

void SetRuntimeFunction_error_GetExceptionSourceRow( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetExceptionSourceRow *func )
{
	rt->direct_funcs.error_GetExceptionSourceRow_func = func ;
	return;
}

void SetRuntimeFunction_error_GetExceptionSourceColumn( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetExceptionSourceColumn *func )
{
	rt->direct_funcs.error_GetExceptionSourceColumn_func = func ;
	return;
}

void SetRuntimeFunction_error_GetExceptionObjectName( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetExceptionObjectName *func )
{
	rt->direct_funcs.error_GetExceptionObjectName_func = func ;
	return;
}

void SetRuntimeFunction_error_GetExceptionFunctionName( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetExceptionFunctionName *func )
{
	rt->direct_funcs.error_GetExceptionFunctionName_func = func ;
	return;
}

void SetRuntimeFunction_error_GetStackTrace( struct ZlangRuntime *rt , ZlangDirectFunction_error_GetStackTrace *func )
{
	rt->direct_funcs.error_GetStackTrace_func = func ;
	return;
}

void SetRuntimeFunction_error_CleanException( struct ZlangRuntime *rt , ZlangDirectFunction_error_CleanException *func )
{
	rt->direct_funcs.error_CleanException_func = func ;
	return;
}

int CallRuntimeFunction_error_ThrowException( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t code , char *message )
{
	return rt->direct_funcs.error_ThrowException_func( rt , obj , code , message );
}

int CallRuntimeFunction_error_HaveException( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char *thrown_flag )
{
	return rt->direct_funcs.error_HaveException_func( rt , obj , thrown_flag );
}

int CallRuntimeFunction_error_GetCode( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *code )
{
	return rt->direct_funcs.error_GetCode_func( rt , obj , code );
}

int CallRuntimeFunction_error_GetMessage( struct ZlangRuntime *rt , struct ZlangObject *obj , char **message )
{
	return rt->direct_funcs.error_GetMessage_func( rt , obj , message );
}

int CallRuntimeFunction_error_GetExceptionSourceFilename( struct ZlangRuntime *rt , struct ZlangObject *obj , char **exception_source_filename )
{
	return rt->direct_funcs.error_GetExceptionSourceFilename_func( rt , obj , exception_source_filename );
}

int CallRuntimeFunction_error_GetExceptionSourceRow( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *exception_source_row )
{
	return rt->direct_funcs.error_GetExceptionSourceRow_func( rt , obj , exception_source_row );
}

int CallRuntimeFunction_error_GetExceptionSourceColumn( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *exception_source_col )
{
	return rt->direct_funcs.error_GetExceptionSourceColumn_func( rt , obj , exception_source_col );
}

int CallRuntimeFunction_error_GetExceptionObjectName( struct ZlangRuntime *rt , struct ZlangObject *obj , char **exception_obj_name )
{
	return rt->direct_funcs.error_GetExceptionObjectName_func( rt , obj , exception_obj_name );
}

int CallRuntimeFunction_error_GetExceptionFunctionName( struct ZlangRuntime *rt , struct ZlangObject *obj , char **exception_func_name )
{
	return rt->direct_funcs.error_GetExceptionFunctionName_func( rt , obj , exception_func_name );
}

int CallRuntimeFunction_error_GetStackTrace( struct ZlangRuntime *rt , struct ZlangObject *obj , char **stack_trace )
{
	return rt->direct_funcs.error_GetStackTrace_func( rt , obj , stack_trace );
}

int CallRuntimeFunction_error_CleanException( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	return rt->direct_funcs.error_CleanException_func( rt , obj );
}

void SetRuntimeFunction_fatal_ThrowException( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_ThrowException *func )
{
	rt->direct_funcs.fatal_ThrowException_func = func ;
	return;
}

void SetRuntimeFunction_fatal_HaveException( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_HaveException *func )
{
	rt->direct_funcs.fatal_HaveException_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetCode( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetCode *func )
{
	rt->direct_funcs.fatal_GetCode_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetMessage( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetMessage *func )
{
	rt->direct_funcs.fatal_GetMessage_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetExceptionSourceFilename( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetExceptionSourceFilename *func )
{
	rt->direct_funcs.fatal_GetExceptionSourceFilename_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetExceptionSourceRow( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetExceptionSourceRow *func )
{
	rt->direct_funcs.fatal_GetExceptionSourceRow_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetExceptionSourceColumn( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetExceptionSourceColumn *func )
{
	rt->direct_funcs.fatal_GetExceptionSourceColumn_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetExceptionObjectName( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetExceptionObjectName *func )
{
	rt->direct_funcs.fatal_GetExceptionObjectName_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetExceptionFunctionName( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetExceptionFunctionName *func )
{
	rt->direct_funcs.fatal_GetExceptionFunctionName_func = func ;
	return;
}

void SetRuntimeFunction_fatal_GetStackTrace( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_GetStackTrace *func )
{
	rt->direct_funcs.fatal_GetStackTrace_func = func ;
	return;
}

void SetRuntimeFunction_fatal_CleanException( struct ZlangRuntime *rt , ZlangDirectFunction_fatal_CleanException *func )
{
	rt->direct_funcs.fatal_CleanException_func = func ;
	return;
}

int CallRuntimeFunction_fatal_ThrowException( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t code , char *message )
{
	return rt->direct_funcs.fatal_ThrowException_func( rt , obj , code , message );
}

int CallRuntimeFunction_fatal_HaveException( struct ZlangRuntime *rt , struct ZlangObject *obj , unsigned char *have )
{
	return rt->direct_funcs.fatal_HaveException_func( rt , obj , have );
}

int CallRuntimeFunction_fatal_GetCode( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *code )
{
	return rt->direct_funcs.fatal_GetCode_func( rt , obj , code );
}

int CallRuntimeFunction_fatal_GetMessage( struct ZlangRuntime *rt , struct ZlangObject *obj , char **message )
{
	return rt->direct_funcs.fatal_GetMessage_func( rt , obj , message );
}

int CallRuntimeFunction_fatal_GetExceptionSourceFilename( struct ZlangRuntime *rt , struct ZlangObject *obj , char **exception_source_filename )
{
	return rt->direct_funcs.fatal_GetExceptionSourceFilename_func( rt , obj , exception_source_filename );
}

int CallRuntimeFunction_fatal_GetExceptionSourceRow( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *exception_source_row )
{
	return rt->direct_funcs.fatal_GetExceptionSourceRow_func( rt , obj , exception_source_row );
}

int CallRuntimeFunction_fatal_GetExceptionSourceColumn( struct ZlangRuntime *rt , struct ZlangObject *obj , int32_t *exception_source_col )
{
	return rt->direct_funcs.fatal_GetExceptionSourceColumn_func( rt , obj , exception_source_col );
}

int CallRuntimeFunction_fatal_GetExceptionObjectName( struct ZlangRuntime *rt , struct ZlangObject *obj , char **exception_obj_name )
{
	return rt->direct_funcs.fatal_GetExceptionObjectName_func( rt , obj , exception_obj_name );
}

int CallRuntimeFunction_fatal_GetExceptionFunctionName( struct ZlangRuntime *rt , struct ZlangObject *obj , char **exception_func_name )
{
	return rt->direct_funcs.fatal_GetExceptionFunctionName_func( rt , obj , exception_func_name );
}

int CallRuntimeFunction_fatal_GetStackTrace( struct ZlangRuntime *rt , struct ZlangObject *obj , char **stack_trace )
{
	return rt->direct_funcs.fatal_GetStackTrace_func( rt , obj , stack_trace );
}

int CallRuntimeFunction_fatal_CleanException( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	return rt->direct_funcs.fatal_CleanException_func( rt , obj );
}

int ThrowErrorException( struct ZlangRuntime *rt , int32_t code , char *message )
{
	if( rt->frequent_objs.error_obj )
		return CallRuntimeFunction_error_ThrowException( rt , rt->frequent_objs.error_obj , code , message );
	else
		return 0;
}

unsigned char HaveErrorException( struct ZlangRuntime *rt )
{
	unsigned char	thrown_flag ;
	CallRuntimeFunction_error_HaveException( rt , rt->frequent_objs.error_obj , & thrown_flag );
	return thrown_flag;
}

int GetErrorCode( struct ZlangRuntime *rt , int32_t *code )
{
	return CallRuntimeFunction_error_GetCode( rt , rt->frequent_objs.error_obj , code );
}

int GetErrorMessage( struct ZlangRuntime *rt , char **message )
{
	return CallRuntimeFunction_error_GetMessage( rt , rt->frequent_objs.error_obj , message );
}

int GetErrorExceptionSourceFilename( struct ZlangRuntime *rt , char **exception_source_filename )
{
	return CallRuntimeFunction_error_GetExceptionSourceFilename( rt , rt->frequent_objs.error_obj , exception_source_filename );
}

int GetErrorExceptionSourceRow( struct ZlangRuntime *rt , int32_t *exception_source_row )
{
	return CallRuntimeFunction_error_GetExceptionSourceRow( rt , rt->frequent_objs.error_obj , exception_source_row );
}

int GetErrorExceptionSourceColumn( struct ZlangRuntime *rt , int32_t *exception_source_col )
{
	return CallRuntimeFunction_error_GetExceptionSourceColumn( rt , rt->frequent_objs.error_obj , exception_source_col );
}

int GetErrorExceptionObjectName( struct ZlangRuntime *rt , char **exception_obj_name )
{
	return CallRuntimeFunction_error_GetExceptionObjectName( rt , rt->frequent_objs.error_obj , exception_obj_name );
}

int GetErrorExceptionFunctionName( struct ZlangRuntime *rt , char **exception_func_name )
{
	return CallRuntimeFunction_error_GetExceptionFunctionName( rt , rt->frequent_objs.error_obj , exception_func_name );
}

int GetErrorStackTrace( struct ZlangRuntime *rt , char **stack_trace )
{
	return CallRuntimeFunction_error_GetStackTrace( rt , rt->frequent_objs.error_obj , stack_trace );
}

int CleanErrorException( struct ZlangRuntime *rt )
{
	return CallRuntimeFunction_error_CleanException( rt , rt->frequent_objs.error_obj );
}

int ThrowFatalException( struct ZlangRuntime *rt , int32_t code , char *message )
{
	if( rt->frequent_objs.fatal_obj )
		return CallRuntimeFunction_fatal_ThrowException( rt , rt->frequent_objs.fatal_obj , code , message );
	else
		return code;
}

unsigned char HaveFatalException( struct ZlangRuntime *rt )
{
	unsigned char	thrown_flag ;
	CallRuntimeFunction_fatal_HaveException( rt , rt->frequent_objs.fatal_obj , & thrown_flag );
	return thrown_flag;
}

int GetFatalCode( struct ZlangRuntime *rt , int32_t *code )
{
	return CallRuntimeFunction_fatal_GetCode( rt , rt->frequent_objs.fatal_obj , code );
}

int GetFatalMessage( struct ZlangRuntime *rt , char **message )
{
	return CallRuntimeFunction_fatal_GetMessage( rt , rt->frequent_objs.fatal_obj , message );
}

int GetFatalExceptionSourceFilename( struct ZlangRuntime *rt , char **exception_source_filename )
{
	return CallRuntimeFunction_fatal_GetExceptionSourceFilename( rt , rt->frequent_objs.fatal_obj , exception_source_filename );
}

int GetFatalExceptionSourceRow( struct ZlangRuntime *rt , int32_t *exception_source_row )
{
	return CallRuntimeFunction_fatal_GetExceptionSourceRow( rt , rt->frequent_objs.fatal_obj , exception_source_row );
}

int GetFatalExceptionSourceColumn( struct ZlangRuntime *rt , int32_t *exception_source_col )
{
	return CallRuntimeFunction_fatal_GetExceptionSourceColumn( rt , rt->frequent_objs.fatal_obj , exception_source_col );
}

int GetFatalExceptionObjectName( struct ZlangRuntime *rt , char **exception_obj_name )
{
	return CallRuntimeFunction_fatal_GetExceptionObjectName( rt , rt->frequent_objs.fatal_obj , exception_obj_name );
}

int GetFatalExceptionFunctionName( struct ZlangRuntime *rt , char **exception_func_name )
{
	return CallRuntimeFunction_fatal_GetExceptionFunctionName( rt , rt->frequent_objs.fatal_obj , exception_func_name );
}

int GetFatalStackTrace( struct ZlangRuntime *rt , char **stack_trace )
{
	return CallRuntimeFunction_fatal_GetStackTrace( rt , rt->frequent_objs.fatal_obj , stack_trace );
}

int CleanFatalException( struct ZlangRuntime *rt )
{
	return CallRuntimeFunction_fatal_CleanException( rt , rt->frequent_objs.fatal_obj );
}

void GetExceptionThrownFlags( struct ZlangRuntime *rt , unsigned char *error_thrown_flag , unsigned char *fatal_thrown_flag )
{
	struct ZlangDirectProperty_error	*error_direct_prop = GetObjectDirectProperty(rt->frequent_objs.error_obj) ;
	struct ZlangDirectProperty_fatal	*fatal_direct_prop = GetObjectDirectProperty(rt->frequent_objs.fatal_obj) ;
	
	if( error_thrown_flag )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "get error_direct_prop->thrown_flag[%d]" , error_direct_prop->thrown_flag )
		(*error_thrown_flag) = error_direct_prop->thrown_flag ;
	}
	if( fatal_thrown_flag )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "get fatal_direct_prop->thrown_flag[%d]" , fatal_direct_prop->thrown_flag )
		(*fatal_thrown_flag) = fatal_direct_prop->thrown_flag ;
	}
	return;
}

void SetExceptionThrownFlags( struct ZlangRuntime *rt , unsigned char error_thrown_flag , unsigned char fatal_thrown_flag )
{
	struct ZlangDirectProperty_error	*error_direct_prop = GetObjectDirectProperty(rt->frequent_objs.error_obj) ;
	struct ZlangDirectProperty_fatal	*fatal_direct_prop = GetObjectDirectProperty(rt->frequent_objs.fatal_obj) ;
	
	error_direct_prop->thrown_flag = error_thrown_flag ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "set error_direct_prop->thrown_flag[%d]" , error_direct_prop->thrown_flag )
	fatal_direct_prop->thrown_flag = fatal_thrown_flag ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "set fatal_direct_prop->thrown_flag[%d]" , fatal_direct_prop->thrown_flag )
	
	return;
}

int GetRuntimeRecursiveDepth( struct ZlangRuntime *rt )
{
	return rt->debug_recursive_depth;
}

void SetRuntimeRecursiveDepth( struct ZlangRuntime *rt , int recursive_depth )
{
	rt->debug_recursive_depth = recursive_depth ;
	return;
}

void OffsetRuntimeRecursizeDepth( struct ZlangRuntime *rt , int recursive_depth_delta )
{
	rt->debug_recursive_depth += recursive_depth_delta ;
	return;
}

char *GetRuntimeSourceFilename( struct ZlangRuntime *rt )
{
	if( rt->travel_token_info == NULL )
		return NULL;
	
	return rt->travel_token_info->source_filename;
}

int32_t GetRuntimeSourceRow( struct ZlangRuntime *rt )
{
	if( rt->travel_token_info == NULL )
		return 0;
	
	return rt->travel_token_info->source_row;
}

int32_t GetRuntimeSourceColumn( struct ZlangRuntime *rt )
{
	if( rt->travel_token_info == NULL )
		return 0;
	
	return rt->travel_token_info->source_col;
}

int CheckOutputParamterStackAndFunctionParameters( struct ZlangRuntime *rt , struct ZlangFunction *func )
{
	struct ZlangObject		*out = NULL ;
	
	out = GetOutputParameterInLocalObjectStack( rt , 1 ) ;
	if( STRCMP( GetCloneObjectName(out) , != , GetFunctionParameterParentObjectName(func->out_param) ) )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED , "out-param ancestor name[%s] not matched with func-out-param parent name[%s]" , GetCloneObjectName(out) , GetFunctionParameterParentObjectName(func->out_param) )
		return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
	}
	
	if( GetOutputParameterCountInLocalObjectStack( rt ) != 1 )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED , "function parameters count not matched" )
		return ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED;
	}
	
	return 0;
}
	
int CheckInputParamterStackAndFunctionParameters( struct ZlangRuntime *rt , struct ZlangFunction *func )
{
	struct ZlangObject		*in = NULL ;
	int				in_params_count ;
	int				in_params_index ;
	struct ZlangFunctionParameter	*func_param = NULL ;
	
	in_params_count = GetInputParameterCountInLocalObjectStack( rt ) ;
	in_params_index = 0 ;
	func_param = NULL ;
	while( ( func_param = TravelFunctionInputParameter( rt , func , func_param ) ) )
	{
		in = GetInputParameterInLocalObjectStack( rt , in_params_index+1 ) ;
		if( in == NULL )
			break;
		
		in_params_index++;
		
		if( STRCMP( func_param->parent_obj_name , == , ZLANG_OBJECT_vargs ) )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ZLANG_OBJECT_vargs found on check out param" )
			return 0;
		}
		else if( STRCMP( GetCloneObjectName(in) , != , GetFunctionParameterParentObjectName(func_param) ) )
		{
			if( STRCMP( GetFunctionParameterParentObjectName(func_param) , != , ZLANG_OBJECT_object ) )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED , "in-param ancestor name[%s] not matched with func-in-param parent name[%s]" , GetCloneObjectName(in) , GetFunctionParameterParentObjectName(func_param) )
				return ZLANG_ERROR_FUNC_PARAMETER_TYPE_NOT_MATCHED;
			}
		}
	}
	if( in_params_index != in_params_count )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED , "function parameters count not matched , count[%d] expect_count[%d]" , in_params_index , in_params_count )
		return ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED;
	}
	
	return 0;
}

struct ZlangRuntime *DuplicateRuntime( struct ZlangRuntime *parent_rt , struct ZlangFunction *func )
{
	struct ZlangRuntime		*rt = NULL ;
	struct ZlangObjectsStackFrame	*local_objs_stack_frame ;
	int				local_objs_stack_frame_curridx ;
	struct ZlangObjectsStackFrame	*tmp_objs_stack_frame ;
	int				tmp_objs_stack_frame_curridx ;
	struct ZlangDefersStackFrame	*defers_stack_frame ;
	int				defers_stack_frame_curridx ;
	struct ZlangObject		*global_obj = NULL ;
	struct ZlangObject		*new_global_obj = NULL ;
	struct ZlangFunction		*global_func = NULL ;
	struct ZlangFunction		*new_global_func = NULL ;
	struct ZlangFunctionParameter	*in_param = NULL ;
	struct ZlangFunctionParameter	*new_in_param = NULL ;
	struct ZlangObject		*out = NULL ;
	int				in_param_count ;
	int				in_param_index ;
	struct ZlangObject		*in = NULL ;
	struct ZlangObject		*obj = NULL ;
	int				nret = 0 ;
	
	rt = ZLMALLOC( sizeof(struct ZlangRuntime) ) ;
	if( rt == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc runtime failed , errno[%d]" , errno )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	memset( rt , 0x00 , sizeof(struct ZlangRuntime) );
	rt->zlang_stack_bottom = (char*) & rt ;

	rt->debug_error_level = parent_rt->debug_error_level ;
	rt->runtime_error_level = parent_rt->runtime_error_level ;
	rt->runtime_error_no = parent_rt->runtime_error_no ;
	rt->full_charset_str = parent_rt->full_charset_str ;
	rt->charset = parent_rt->charset ;
	INIT_LIST_HEAD( & (rt->source_file_datapage_list) );
	INIT_LIST_HEAD( & (rt->token_datapage_list) );
	INIT_LIST_HEAD( & (rt->include_files_list) );
	INIT_LIST_HEAD( & (rt->import_files_list) );
	INIT_LIST_HEAD( & (rt->global_order_imported_objs_list) );
	INIT_LIST_HEAD( & (rt->global_intercepts) );
	INIT_LIST_HEAD( & (rt->object_prop_intercepts) );
	INIT_LIST_HEAD( & (rt->global_literal_objs_list) );
	INIT_LIST_HEAD( & (rt->objs_cache) );
	INIT_LIST_HEAD( & (rt->props_entis_cache) );
	INIT_LIST_HEAD( & (rt->funcs_entis_cache) );
	rt->zlang_max_stack_size = atol(ZLANG_MAX_STACK_SIZE) ;
	rt->zlang_alart_stack_depth = (signed long)((double)(rt->zlang_max_stack_size)*0.95) ;
	
	nret = InitObjectStack( rt , & (rt->local_objs_stack) , ZLANG_LOCAL_OBJECTS_STACK_SIZE_DEFAULT , ZLANG_LOCAL_OBJECTS_STACK_INCREASE_SIZE ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "InitObjectStack local_objs_stack failed" )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "InitObjectStack local_objs_stack ok" )
	
	nret = InitLocalObjecsStackFrameArray( rt ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "InitLocalObjecsStackFrameArray failed" )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	
	local_objs_stack_frame = GetCurrentLocalObjectsStackFrame( rt ) ;
	if( local_objs_stack_frame == NULL )
	{
		SET_RUNTIME_ERROR(rt, RUNTIME_ERROR, nret, "GetCurrentLocalObjectsStackFrame failed")
		CopyRuntimeError(parent_rt, rt);
		return NULL;
	}
	local_objs_stack_frame_curridx = GetCurrentLocalObjectsStackFrameIndex( rt ) ;
	TEST_RUNTIME_DEBUG( rt )
	{
		PRINT_TABS_AND_FORMAT( rt , "alloc local_objs_stack[%p] ok , local_objs_stack_size[%d] local_objs_stacks_info[%d][%s]-[%d][%d][%d][%d]" , rt->local_objs_stack.objs_stack , rt->local_objs_stack.objs_stack_size , local_objs_stack_frame_curridx , local_objs_stack_frame->full_func_name , local_objs_stack_frame->stack_bottom , local_objs_stack_frame->stack_in_params_top , local_objs_stack_frame->stack_out_params_top , local_objs_stack_frame->stack_local_var_top );
	}
	
	nret = InitObjectStack( rt , & (rt->tmp_objs_stack) , ZLANG_TMP_OBJECTS_STACK_SIZE_DEFAULT , ZLANG_TMP_OBJECTS_STACK_INCREASE_SIZE ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "InitObjectStack tmp_objs_stack failed" )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "InitObjectStack tmp_objs_stack ok" )
	
	nret = InitTmpObjecsStackFrameArray( rt ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "InitTmpObjecsStackFrameArray failed" )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	
	tmp_objs_stack_frame = GetCurrentTmpObjectsStackFrame( rt ) ;
	if( tmp_objs_stack_frame == NULL )
	{
		SET_RUNTIME_ERROR(rt, RUNTIME_ERROR, nret, "GetCurrentTmpObjectsStackFrame failed")
		CopyRuntimeError(parent_rt, rt);
		return NULL;
	}
	tmp_objs_stack_frame_curridx = GetCurrentTmpObjectsStackFrameIndex( rt ) ;
	TEST_RUNTIME_DEBUG( rt )
	{
		PRINT_TABS_AND_FORMAT( rt , "alloc tmp_objs_stack[%p] ok , tmp_objs_stack_size[%d] tmp_objs_stacks_info[%d][%s]-[%d][%d][%d][%d]" , rt->tmp_objs_stack.objs_stack , rt->tmp_objs_stack.objs_stack_size , tmp_objs_stack_frame_curridx , tmp_objs_stack_frame->full_func_name , tmp_objs_stack_frame->stack_bottom , tmp_objs_stack_frame->stack_in_params_top , tmp_objs_stack_frame->stack_out_params_top , tmp_objs_stack_frame->stack_local_var_top );
	}
	
	nret = InitDefersStack( rt , & (rt->defers_stack) , ZLANG_DEFERS_STACK_SIZE_DEFAULT , ZLANG_DEFERS_STACK_INCREASE_SIZE ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "InitDefersStack tmp_objs_stack failed" )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "InitDefersStack defers_stack ok" )
	
	nret = InitDefersStackFrameArray( rt ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "InitDefersStackFrameArray failed" )
		CopyRuntimeError( parent_rt , rt );
		return NULL;
	}
	
	defers_stack_frame = GetCurrentDefersStackFrame( rt ) ;
	if( defers_stack_frame == NULL )
	{
		SET_RUNTIME_ERROR(rt, RUNTIME_ERROR, nret, "GetCurrentDefersStackFrame failed")
		CopyRuntimeError(parent_rt, rt);
		return NULL;
	}
	defers_stack_frame_curridx = GetCurrentDefersStackFrameIndex( rt ) ;
	TEST_RUNTIME_DEBUG( rt )
	{
		PRINT_TABS_AND_FORMAT( rt , "alloc defers_stack[%p] ok , defers_stack_size[%d] defers_stacks_info[%d][%s]-[%d][%d]" , rt->defers_stack.defers_stack , rt->defers_stack.defers_stack_size , defers_stack_frame_curridx , defers_stack_frame->full_func_name , defers_stack_frame->stack_bottom , defers_stack_frame->stack_top );
	}
	
	memcpy( & (rt->invoke_funcs) , & (parent_rt->invoke_funcs) , sizeof(struct ZlangRuntimeInvokeFunctions) );
	
	memcpy( & (rt->direct_funcs) , & (parent_rt->direct_funcs) , sizeof(struct ZlangRuntimeDirectFunctions) );
	
	list_for_each_entry( global_obj , & (parent_rt->global_order_imported_objs_list) , struct ZlangObject , obj_order_imported_node )
	{
		new_global_obj = AllocObject( rt ) ;
		if( new_global_obj == NULL )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "AllocObject failed[%d]" , nret )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		
		nret = ReferObject( rt , new_global_obj , global_obj ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ReferObject failed[%d]" , nret )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		
		nret = SetObjectName( rt , new_global_obj , GetObjectName(global_obj) ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "SetObjectName failed[%d]" , nret )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		
		nret = ImportObjectToGlobalObjectsHeap( rt , new_global_obj , NULL ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "ImportObjectToGlobalObjectsHeap[%s] failed[%d]" , GetObjectName(global_obj) , nret )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		else
		{
			TEST_RUNTIME_DEBUG(rt){ PRINT_TABS(rt) printf( "ImportObjectToGlobalObjectsHeap[%s] ok , " , GetObjectName(global_obj) ); DebugPrintObject(rt,global_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE }
		}
	}
	
	TEST_RUNTIME_DEBUG( rt )
	{
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.zobject_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.zruntime_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.error_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.fatal_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.string_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.bool_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.short_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.ushort_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.int_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.uint_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.long_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.ulong_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.float_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.double_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.array_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
		PRINT_TABS(rt) printf( "rt->" ); DebugPrintObject(rt,rt->frequent_objs.functionptr_obj); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE
	}
	
	global_func = NULL ;
	for( ; ; )
	{
		global_func = TravelFunctionInRuntimeFunctionsTreeByFunctionName( parent_rt , global_func ) ;
		if( global_func == NULL )
			break;
		
		new_global_func = (struct ZlangFunction *)ZLMALLOC( sizeof(struct ZlangFunction) ) ;
		if( new_global_func == NULL )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for func failed" )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		memset( new_global_func , 0x00 ,  sizeof(struct ZlangFunction) );
		new_global_func->func_name = ZLSTRDUP( global_func->func_name ) ;
		if( new_global_func->func_name == NULL )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for func member failed" )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		new_global_func->full_func_name = ZLSTRDUP( global_func->full_func_name ) ;
		if( new_global_func->full_func_name == NULL )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for func member failed" )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		INIT_LIST_HEAD( & (new_global_func->in_params) );
		in_param = NULL ;
		while( ( in_param = TravelFunctionInputParameter( rt , global_func , in_param ) ) )
		{
			new_in_param = AddFunctionInputParameterInFunction( rt , new_global_func , in_param->parent_obj_name , in_param->obj_name ) ;
			if( new_in_param == NULL )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "add in param to new global function failed" )
				CopyRuntimeError( parent_rt , rt );
				return NULL;
			}
		}
		if( global_func->out_param )
		{
			if( SetFunctionOutputParameterInFunction( rt , new_global_func , global_func->out_param->parent_obj_name ) == NULL )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for func member failed" )
				CopyRuntimeError( parent_rt , rt );
				return NULL;
			}
		}
		else
		{
			new_global_func->out_param = NULL ;
		}
		
		new_global_func->invoke_func = global_func->invoke_func ;
		
		new_global_func->func_begin_token_datapage_header = global_func->func_begin_token_datapage_header ;
		new_global_func->func_begin_token_dataunit = global_func->func_begin_token_dataunit ;
		new_global_func->func_end_over_token_datapage_header = global_func->func_end_over_token_datapage_header ;
		new_global_func->func_end_over_token_dataunit = global_func->func_end_over_token_dataunit ;
		
		CopySynchronizeFunction( new_global_func , global_func );
		
		nret = LinkFunctionToRuntimeFunctionsTreeByFunctionName( rt , new_global_func ) ;
		if( nret )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "LinkFunctionToRuntimeFunctionsTreeByFunctionName failed" )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		
		nret = LinkFunctionToRuntimeFunctionsTreeByFullFunctionName( rt , new_global_func ) ;
		if( nret )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , nret , "LinkFunctionToRuntimeFunctionsTreeByFullFunctionName failed" )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
		
		TEST_RUNTIME_DEBUG(rt){ PRINT_TABS(rt) printf( "global function : \n" ); DebugPrintFunction( rt , NULL , new_global_func ); }
	}
	
	if( ! list_empty( & (parent_rt->global_intercepts) ) )
	{
		memcpy( & (rt->global_intercepts) , & (parent_rt->global_intercepts) , sizeof(struct list_head) );
	}
	if( ! list_empty( & (parent_rt->object_prop_intercepts) ) )
	{
		memcpy( & (rt->object_prop_intercepts) , & (parent_rt->object_prop_intercepts) , sizeof(struct list_head) );
	}
	if( ! rb_first( & (parent_rt->global_interfaces) ) )
	{
		memcpy( & (rt->global_interfaces) , & (parent_rt->global_interfaces) , sizeof(struct rb_root) );
	}
	
	local_objs_stack_frame->full_func_name = new_global_func->full_func_name ;
	
	local_objs_stack_frame->stack_in_params_top = local_objs_stack_frame->stack_local_var_top ;
	local_objs_stack_frame->stack_out_params_top = local_objs_stack_frame->stack_local_var_top ;
	
	if( func )
	{
		in_param_count = GetInputParameterCountInLocalObjectStack( parent_rt );
		in_param_index = 0 ;
		list_for_each_entry( in_param , & (func->in_params) , struct ZlangFunctionParameter , this_param )
		{
			in_param_index++;
			
			obj = GetInputParameterInLocalObjectStack( parent_rt , in_param_index ) ;
			if( obj == NULL )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED , "Start(...) for func[%s][%s] input parameters count not matched" , func->func_name , func->full_func_name )
				CopyRuntimeError( parent_rt , rt );
				return NULL;
			}
			
			in = ReferObjectInLocalStack( rt , in_param->obj_name , obj ) ;
			if( in == NULL )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , GetRuntimeErrorNo(rt) , "ReferObjectInLocalStack in param failed" )
				CopyRuntimeError( parent_rt , rt );
				return NULL;
			}
			else
			{
				TEST_RUNTIME_DEBUG( rt ) { PRINT_TABS(rt) printf( "ReferObjectInLocalStack in param ok , " ); DebugPrintObject(rt,in); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE }
			}
			
			if( IsAtomicObject(obj) )
			{
				CopyAtomicLock( in , obj );
			}
		}
		if( in_param_index != in_param_count )
		{
			SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_FUNC_PARAMETERS_COUNT_NOT_MATCHED , "func '%s' in parameters count not matched with thread.Start" , func->full_func_name )
			CopyRuntimeError( parent_rt , rt );
			return NULL;
		}
	}
	local_objs_stack_frame->stack_in_params_top = local_objs_stack_frame->stack_local_var_top ;
	
	if( func )
	{
		if( func->out_param && STRCMP( func->out_param->parent_obj_name , != , ZLANG_OBJECT_void ) )
		{
			obj = QueryGlobalObjectByObjectName( parent_rt , func->out_param->parent_obj_name ) ;
			TEST_RUNTIME_DEBUG( rt ) { PRINT_TABS(rt) printf( "QueryGlobalObjectByObjectName obj[%s] return " , func->out_param->parent_obj_name ); DebugPrintObject( parent_rt , obj ); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE }
			if( obj == NULL )
			{
				SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_OBJECT_NOT_IMPORTED_OR_DECLARED , "object '%s' not imported" , func->out_param->parent_obj_name )
				CopyRuntimeError( parent_rt , rt );
				return NULL;
			}
			
			out = CloneObjectInLocalStack( rt , NULL , obj ) ;
			if( out == NULL )
			{
				CopyRuntimeError( parent_rt , rt );
				return NULL;
			}
			else
			{
				TEST_RUNTIME_DEBUG( rt ) { PRINT_TABS(rt) printf( "CreateObjectInLocalStack out param ok , " ); DebugPrintObject(rt,out); PRINT_SOURCE_FILE_LINE PRINT_NEWLINE }
			}
		}
	}
	local_objs_stack_frame->stack_out_params_top = local_objs_stack_frame->stack_local_var_top ;
	
	TEST_RUNTIME_DEBUG( rt )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "duplicate runtime stack" )
		DebugStack( rt );
	}
	
	return rt;
}

int InvokeEntryFunction( struct ZlangRuntime *rt , struct ZlangObject *in_obj , struct ZlangFunction *entry_func )
{
	struct ZlangObject			*bak_in_obj = NULL ;
	struct ZlangFunction			*bak_in_func = NULL ;
	int					nret = 0 ;
	
	_zlang_rt = rt ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "call entry func function[%s][%s]" , entry_func->func_name , entry_func->full_func_name )
	bak_in_obj = rt->in_obj ;
	bak_in_func = rt->in_func ;
	rt->in_obj = in_obj ;
	rt->in_func = entry_func ;
	rt->travel_token_datapage_header = rt->in_func->func_begin_token_datapage_header ;
	rt->travel_token_dataunit = rt->in_func->func_begin_token_dataunit ;
	nret = InterpretStatementSegment( rt , NULL ) ;
	rt->in_obj = bak_in_obj ;
	rt->in_func = bak_in_func ;
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "entry func function[%s][%s] return[%d]" , entry_func->func_name , entry_func->full_func_name , nret )
	if( nret == ZLANG_INFO_CONTINUE || nret == ZLANG_INFO_BREAK || nret == ZLANG_INFO_RETURN || nret == ZLANG_INFO_END_OF_STATEMENT_SEGMENT )
	{
		nret = 0 ;
	}
	
	TEST_RUNTIME_DEBUG( rt )
	{
		DebugStack( rt );
	}
	
	return nret;
}

void FreeRuntime( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangObject	*next_obj = NULL ;
	
	TEST_RUNTIME_DEBUG( rt )
	{
		DebugStack( rt );
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PopupLocalObjectsStack" )
	PopupLocalObjectsStackFrame( rt );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PopupTmpObjectsStack" )
	PopupTmpObjectsStackFrame( rt );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "PopupDefersStack" )
	PopupDefersStackFrame( rt );
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CleanObjectsStack local_objs_stack" )
	CleanObjectsStack( rt , & (rt->local_objs_stack) );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CleanLocalObjecsStackFrameArray" )
	CleanLocalObjecsStackFrameArray( rt );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CleanObjectsStack tmp_objs_stack" )
	CleanObjectsStack( rt , & (rt->tmp_objs_stack) );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CleanTmpObjecsStackFrameArray" )
	CleanTmpObjecsStackFrameArray( rt );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CleanDefersStack defers_stack" )
	CleanDefersStack( rt , & (rt->defers_stack) );
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CleanDefersStackFrameArray" )
	CleanDefersStackFrameArray( rt );
	
	DestroyRuntimeObjectsHeap( rt );
	DestroyRuntimeFunctionsTreeByFunctionName( rt );
	DestroyRuntimeFunctionsTreeByFullFunctionName( rt );
	
	FreeObjectsCache( rt );
	FreePropertiesEntityCache( rt );
	list_for_each_entry_safe( obj , next_obj , & (rt->global_literal_objs_list) , struct ZlangObject , obj_list_node )
	{
		DestroyObject( rt , obj );
	}
	FreeFunctionsEntityCache( rt );
	
	ZLFREE( rt );
	
	return;
}

void DebugPrintRawMemory()
{
	struct ZlMemBlocks	*memblocks = NULL ;
	struct ZlMemBlock	*memblock = NULL ;
	char			*alloc_base = NULL ;
	char			*action = NULL ;
	size_t			alloc_size ;
	char			*source_file = NULL ;
	size_t			source_line ;
	unsigned char		*p = NULL ;
	size_t			i ;
	
	ZlWriteLockMemblocks();
	{
		printf( "--- ZLMALLOC --- BEGIN-DUMP --- alloc blocks %zu - alloc memory %zu bytes - total memory %zu bytes ---\n" , ZlGetUsingBlocks() , ZlGetUsingMemory() , ZlGetUsingTotalMemory() );
		
		memblocks = ZlGetMemBlocks() ;
		memblock = NULL ;
		while( ( memblock = ZlTravelMemoryBlock(memblocks,memblock) ) )
		{
			alloc_base = ZlGetMemblockBase(memblock) ;
			action = ZlGetMemblockAction(memblock) ;
			alloc_size = ZlGetMemblockSize(memblock) ;
			source_file = ZlGetMemblockSourceFile(memblock) ;
			source_line = ZlGetMemblockSourceLine(memblock) ;
			printf( "- %s %zu %s:%zu [" , action , alloc_size , source_file , source_line );
			
			for( i = 0 , p = (unsigned char*)alloc_base ; i < alloc_size ; i++ , p++ )
			{
				if( i >= 32 )
					break;
				
				if( isprint(*p) )
					putchar( (*p) );
				else
					break;
			}
			if( i >= 32 )
				printf( "..." );
			
			printf( "]\n" );
		}
		
		printf( "--- ZLMALLOC --- END-DUMP ---\n" );
	}
	ZlUnlockMemblocks();
	
	return;
}

void DebugPrintStackMemory( struct ZlangRuntime *rt )
{
	struct ZlangObjectsStackFrame	*objs_stack_frame = NULL ;
	int				objs_stack_index ;
	int				local_objs_index , local_objs_count ;
	int				in_param_index , in_param_count ;
	int				out_param_index , out_param_count ;
	struct ZlangObject		*obj = NULL ;
	size_t				summarized_obj_size ;
	size_t				summarized_direct_prop_size ;
	struct ZlangObject		*tostr_obj = NULL ;
	char				*str = NULL ;
	int32_t				str_len ;
	int				nret = 0 ;
	
	objs_stack_frame = GetCurrentLocalObjectsStackFrame( rt ) ;
	objs_stack_index = GetCurrentLocalObjectsStackFrameIndex( rt ) ;
	while( objs_stack_index >= 0 )
	{
		printf( "--- STACK-MEMORY --- FRAME %d --- FUNCTION %s ---\n" , objs_stack_index , GetObjectsStackFullFuncName(objs_stack_frame) );
		
		local_objs_count = GetLocalObjectCountInStackFrame( rt , objs_stack_frame ) ;
		out_param_count = GetOutputParameterCountInStackFrame( rt , objs_stack_frame ) ;
		in_param_count = GetInputParameterCountInStackFrame( rt , objs_stack_frame ) ;
		
		for( local_objs_index = 1 ; local_objs_index <= local_objs_count ; local_objs_index++ )
		{
			obj = GetLocalObjectInStackFrame( rt , objs_stack_frame , local_objs_index ) ;
			
			summarized_obj_size = 0 ;
			summarized_direct_prop_size = 0 ;
			SummarizeObjectSize( rt , obj , & summarized_obj_size , & summarized_direct_prop_size );
			
			tostr_obj = CloneStringObject( rt , NULL ) ;
			if( tostr_obj == NULL )
				return;
			
			if( obj->funcs_enti && obj->funcs_enti->direct_funcs && obj->funcs_enti->direct_funcs->to_string_func )
			{
				nret = obj->funcs_enti->direct_funcs->to_string_func( rt , obj , & tostr_obj ) ;
				if( nret )
				{
					DestroyObject( rt , tostr_obj );
					return;
				}
			}
			
			CallRuntimeFunction_string_GetStringValue( rt , tostr_obj , & str , & str_len );
			
			printf( "LOCAL-OBJ [%s] %zu %zu [%.*s]\n" , GetObjectName(obj) , summarized_obj_size , summarized_direct_prop_size , str_len,str );
			
			DestroyObject( rt , tostr_obj );
		}
		
		for( out_param_index = 1 ; out_param_index <= out_param_count ; out_param_index++ )
		{
			obj = GetOutputParameterInStackFrame( rt , objs_stack_frame , out_param_index ) ;
			
			summarized_obj_size = 0 ;
			summarized_direct_prop_size = 0 ;
			SummarizeObjectSize( rt , obj , & summarized_obj_size , & summarized_direct_prop_size );
			
			tostr_obj = CloneStringObject( rt , NULL ) ;
			if( tostr_obj == NULL )
				return;
			
			if( obj->funcs_enti && obj->funcs_enti->direct_funcs && obj->funcs_enti->direct_funcs->to_string_func )
			{
				nret = obj->funcs_enti->direct_funcs->to_string_func( rt , obj , & tostr_obj ) ;
				if( nret )
				{
					DestroyObject( rt , tostr_obj );
					return;
				}
			}
			
			CallRuntimeFunction_string_GetStringValue( rt , tostr_obj , & str , & str_len );
			
			printf( "OUT-PARAM [%s] %zu %zu [%.*s]\n" , GetObjectName(obj) , summarized_obj_size , summarized_direct_prop_size , str_len,str );
			
			DestroyObject( rt , tostr_obj );
		}
		
		for( in_param_index = 1 ; in_param_index <= in_param_count ; in_param_index++ )
		{
			obj = GetInputParameterInStackFrame( rt , objs_stack_frame , in_param_index ) ;
			
			summarized_obj_size = 0 ;
			summarized_direct_prop_size = 0 ;
			SummarizeObjectSize( rt , obj , & summarized_obj_size , & summarized_direct_prop_size );
			
			tostr_obj = CloneStringObject( rt , NULL ) ;
			if( tostr_obj == NULL )
				return;
			
			if( obj->funcs_enti && obj->funcs_enti->direct_funcs && obj->funcs_enti->direct_funcs->to_string_func )
			{
				nret = obj->funcs_enti->direct_funcs->to_string_func( rt , obj , & tostr_obj ) ;
				if( nret )
				{
					DestroyObject( rt , tostr_obj );
					return;
				}
			}
			
			CallRuntimeFunction_string_GetStringValue( rt , tostr_obj , & str , & str_len );
			
			printf( "IN-PARAM [%s] %zu %zu [%.*s]\n" , GetObjectName(obj) , summarized_obj_size , summarized_direct_prop_size , str_len,str );
			
			DestroyObject( rt , tostr_obj );
		}
		
		objs_stack_frame = GetPreviousObjectsStackFrame( rt , objs_stack_frame ) ;
		objs_stack_index--;
	}
	
	printf( "--- STACK-MEMORY --- END-DUMP ---\n" );
	
	return;
}

void DebugPrintHeapMemory( struct ZlangRuntime *rt )
{
	struct ZlangObject		*obj = NULL ;
	size_t				summarized_obj_size ;
	size_t				summarized_direct_prop_size ;
	struct ZlangObject		*tostr_obj = NULL ;
	char				*str = NULL ;
	int32_t				str_len ;
	int				nret = 0 ;
	
	printf( "--- HEAP-MEMORY ---\n" );
	
	obj = NULL ;
	for( ; ; )
	{
		obj = TravelObjectInRuntimeObjectsHeapByObjectName( rt , obj ) ;
		if( obj == NULL )
			break;
		
		summarized_obj_size = 0 ;
		summarized_direct_prop_size = 0 ;
		SummarizeObjectSize( rt , obj , & summarized_obj_size , & summarized_direct_prop_size );
		
		tostr_obj = CloneStringObject( rt , NULL ) ;
		if( tostr_obj == NULL )
			return;
		
		if( obj->funcs_enti && obj->funcs_enti->direct_funcs && obj->funcs_enti->direct_funcs->to_string_func )
		{
			nret = obj->funcs_enti->direct_funcs->to_string_func( rt , obj , & tostr_obj ) ;
			if( nret )
			{
				DestroyObject( rt , tostr_obj );
				return;
			}
		}
		
		CallRuntimeFunction_string_GetStringValue( rt , tostr_obj , & str , & str_len );
		
		printf( "GLOBAL-OBJ [%s] %zu %zu [%.*s]\n" , GetObjectName(obj) , summarized_obj_size , summarized_direct_prop_size , str_len,str );
		
		DestroyObject( rt , tostr_obj );
	}
	
	printf( "--- HEAP-MEMORY --- END-DUMP ---\n" );
	
	return;
}

